﻿/*
 * Nix PBEM Game Engine.
 * Copyright (C) 2008, Lauris Bukšis-Haberkorns
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

using System;
using System.Collections.Generic;
using System.Text;

using Nix.PBeM.Engine.DataTypes.Orders;
using Nix.PBeM.Engine.DataSources;
using Nix.PBeM.Engine.DataTypes;

namespace Nix.PBeM.Engine.Process.Orders
{
	public class AcceptOrder : OrderBase
	{
		/// <summary>
		/// Initializes a new instance of the <see cref="AcceptOrder"/> class.
		/// </summary>
		public AcceptOrder ()
			: base("ACCEPT")
		{
			this.Syntax = string.Format("{0} unit-id", this.Keyword);
			this.Description = "This order executes when the designated unit attempts to STACK itself under your leadership. The unit is allowed to do so, regardless of the stance toward its faction.";
			this.Type = OrderType.Immediate;
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="AcceptOrder"/> class.
		/// </summary>
		/// <param name="entity">The entity.</param>
		/// <param name="parser">The parser.</param>
		public AcceptOrder ( OrderEntity entity, StringLineParser parser )
			: this ()
		{
			this.Entity = entity;
			this.Parser = parser;
		}

		/// <summary>
		/// Create order instance.
		/// </summary>
		/// <param name="entity">The entity.</param>
		/// <returns>Order instance.</returns>
		public override OrderBase Create ( OrderEntity entity, StringLineParser parser )
		{
			return new AcceptOrder(entity, parser);
		}

		private Unit unit = null;

		/// <summary>
		/// Gets the unit that will be allowed to stack.
		/// </summary>
		/// <value>The unit.</value>
		public Unit Unit
		{
			get { return unit; }
		}

		public override void Parse ()
		{
			if ( this.Entity.GetType() != typeof(Unit) )
				throw new OrderParseException("This order can be specified only for unit.");

			string utag = this.Parser.GetOptionalWord();
			if ( string.IsNullOrEmpty(utag) )
				throw new OrderParseException("Unit id not sepcified.");
			this.unit = Engine.Instance.FindUnit(utag);
			if (this.unit == null)
				throw new OrderParseException("Invalid unit id specified.");
			if (this.unit.Faction == ((Unit)this.Entity).Faction)
				throw new OrderParseException("Unit belongs to your faction. Accept has no sence.");
		}

		/// <summary>
		/// Order duration.
		/// </summary>
		/// <value></value>
		public override int Duration
		{
			get
			{
				return base.Duration;
			}
			set
			{
				// Allow setting only duration 1 or 0 when executed
				if ( value > 1 || value < 0 )
					base.Duration = 1;
				else
					base.Duration = value;
			}
		}

		/// <summary>
		/// Executes this order.
		/// </summary>
		public override void Execute ()
		{
			// Order will be removed/executed when unit tries to stack under this unit.
			((Unit)this.Entity).AddAcceptOrder(this);
			this.ExecutionFailed = true;
		}

		public void DoExecute()
		{
			this.Entity.AddEventMessage(string.Format("Accepting {0}.", this.Unit));
			((Unit)this.Entity).RemoveAcceptOrder(this);
			this.CompleteExecution();
		}
	}
}
